// #include "util.hpp"
// #include "level.hpp"
// #include "message.hpp"
// #include "format.hpp"
// #include "sink.hpp"
// #include <unistd.h>

// /*扩展一个以时间作为日志文件滚动切换类型的日志落地模块
//    1.以时间进行文件滚动，实际上是以时间段进行滚动
//        实现思想：以当前系统时间，取模获得时间段大小，可以得到当前时间段是第几个时间段
//            time(nullptr)%gap;
//            每次以当前系统时间取模，判断与当前文件的时间段是否一致，不一致代表不是同一个时间段
//    */
// // 使用枚举来确定时间段的大小
// enum class TimeGap
// {
//     GAP_SECOND,
//     GAP_MINUTE,
//     GAP_HOUR,
//     GAP_DAY,
// };

// class RollByTimeSink : public log::LogSink
// {
// public:
//     RollByTimeSink(const std::string &basename, TimeGap gap_type) : _basename(basename)
//     {
//         switch (gap_type)
//         {
//         case TimeGap::GAP_SECOND:
//             _gap_size = 1;
//             break; // 以秒为时间段
//         case TimeGap::GAP_MINUTE:
//             _gap_size = 60;
//             break; // 以分钟为时间段
//         case TimeGap::GAP_HOUR:
//             _gap_size = 3600;
//             break; // 以小时为时间段
//         case TimeGap::GAP_DAY:
//             _gap_size = 3600 * 24;
//             break; // 以天为时间段
//         }
//         _cur_gap = _gap_size==1?log::util::Date::now():log::util::Date::now() / _gap_size; // 获取当前是第几个时间段;前面是 _gap_size == 1 的情况
//         // 创建文件
//         std::string filename = createNewFile();
//         log::util::File::createDirectory(log::util::File::path(filename));
//         _ofs.open(filename, std::ios::binary | std::ios::app);
//         assert(_ofs.is_open());
//     }
//     // 将日志消息写入到标准输出，判断当前时间是否是当前文件的时间段，不是就要切换文件。
//     void log(const char *Date, size_t len)
//     {
//         time_t cur = log::util::Date::now(); // 获取当前系统时间,时间戳
//         if ((cur / _gap_size) != _cur_gap)//（每次写日志时判断当前的时间段与上次的时间段是否是一致得，一致的话就写入，不一致就创建新文件）
//         {
//             _ofs.close();                                          // 打开文件，就必须关闭文件（这里关闭以前的文件）
//             std::string pathname = createNewFile();                // 创建新文件
//             _cur_gap = _gap_size==1?log::util::Date::now():log::util::Date::now() / _gap_size; // 获取当前是第几个时间段
//             _ofs.open(pathname, std::ios::binary | std::ios::app); // 打开文件 二进制可写可追加权限
//             assert(_ofs.is_open());                                // 打开失败就报错
//         }
//         _ofs.write(Date, len);
//         assert(_ofs.good()); // 检测文件流状态和文件读写过程是否正常
//     }

// protected:
//     // 创建一个新文件，不需要用户去创建，所有我们把权限设置为私有
//     std::string createNewFile()
//     {
//         // 获取系统时间，以时间来构造文件名的扩展名
//         time_t t = log::util::Date::now();
//         struct tm lt;
//         localtime_r(&t, &lt);
//         std::stringstream filename;
//         filename << _basename;
//         filename << lt.tm_year + 1900;
//         filename << lt.tm_mon + 1;
//         filename << lt.tm_mday;
//         filename << lt.tm_hour;
//         filename << lt.tm_min;
//         filename << lt.tm_sec;
//         filename << ".log";
//         return filename.str();
//     }
// private:
//     std::string _basename; // 基本文件名
//     std::ofstream _ofs;    // 会默认以写的方式打开文件
//     size_t _cur_gap;       // 当前是第几个时间段
//     size_t _gap_size;      // 时间段的大小
// };

// // int main()
// // {
// //     // std::cout << log::util::Date::now() << std::endl;

// //     // std::string pathname = "a.txt";

// //     // log::util::File::createDirectory(log::util::File::path(pathname));

// //     // std::cout<<log::LogLevel::toString(log::LogLevel::value::DEBUG)<<std::endl;
// //     // std::cout<<log::LogLevel::toString(log::LogLevel::value::INFO)<<std::endl;
// //     // std::cout<<log::LogLevel::toString(log::LogLevel::value::ERROR)<<std::endl;
// //     // std::cout<<log::LogLevel::toString(log::LogLevel::value::WARN)<<std::endl;
// //     // std::cout<<log::LogLevel::toString(log::LogLevel::value::FATAL)<<std::endl;
// //     // std::cout<<log::LogLevel::toString(log::LogLevel::value::OFF)<<std::endl;
// //     // std::cout<<log::LogLevel::toString(log::LogLevel::value::UNKNOW)<<std::endl;

// //     // log::LogMsg msg(log::LogLevel::value::INFO, 53, "main.c", "root", "格式化功能测试...");
// //     // log::Formatter fmt;
// //     // // 边缘情况测试
// //     // // log::Formatter fmt("abc%%ab%g%g%gc[%d{%H:%M:%S}]  %m%n"); // 没有 %g 格式字符
// //     // // log::Formatter fmt("abc%%abc[%d{%H:%M:%S}]%m%n");// 测试 %%
// //     // // log::Formatter fmt("abc%%abc[%d{%H:%M:%S}]%m%n{"); // 测试花括号
// //     // // log::Formatter fmt("abc%%abc[%d{%H:%M:%S}]%m%"); // 末尾只带 %，没有格式化字符
// //     // std::string str = fmt.format(msg);
// //     // std::cout << str << std::endl;

// //     // 日志落地模块的测试
// //     log::LogMsg msg(log::LogLevel::value::INFO, 53, "main.c", "root", "格式化功能测试...");
// //     log::Formatter fmt;
// //     std::string str = fmt.format(msg);
// //     // 设置落地方向
// //     log::LogSink::ptr stdout_lsp = log::SinkFactory::create<log::StdoutSink>();                                    // 标准输出落地
// //     log::LogSink::ptr file_lsp = log::SinkFactory::create<log::FileSink>("./logfile/test.log");                    // 文件落地方式
// //     log::LogSink::ptr roll_lsp = log::SinkFactory::create<log::RollBySizeSink>("./logfile/roll-", 1024 * 1024); // 滚动文件落地方式，大小为 1 兆
// //     // 通过指针去控制打印的日志
// //     stdout_lsp->log(str.c_str(), str.size());
// //     file_lsp->log(str.c_str(), str.size());

// //     size_t cursize = 0;
// //     size_t count = 0;
// //     // 用滚动文件的方法希望生产10个文件，一个文件 1 兆
// //     while (cursize < 1024 * 1024 * 10)
// //     {
// //         std::string tmp = std::to_string(count++) + str; // 给日志标号
// //         roll_lsp->log(tmp.c_str(), tmp.size());
// //         cursize += tmp.size();
// //     }
// //     return 0;
// // }

// int main()
// {
//      // 日志落地扩展模块的测试
//     log::LogMsg msg(log::LogLevel::value::INFO, 53, "main.c", "root", "格式化功能测试...");
//     log::Formatter fmt;
//     std::string str = fmt.format(msg);
//     // 设置落地方向
//     log::LogSink::ptr time_lsp = log::SinkFactory::create<RollByTimeSink>("./logfile/rool-", TimeGap::GAP_SECOND);
//     time_t old=log::util::Date::now();//获取当前系统时间
//     while (log::util::Date::now()< old + 3)//写3秒的数据
//     {
//         time_lsp->log(str.c_str(), str.size());
//         usleep(1000);//等待1毫秒
//     }
//     return 0;
// }

// 测试代码
// #include "util.hpp"
// #include "level.hpp"
// #include "message.hpp"
// #include "format.hpp"
// #include "sink.hpp"
// #include "logger.hpp"
// #include <unistd.h>

// int main()
// {

//     // 日志器模块：同步日志器
//     std::string logger_name = "sync_logger";
//     log::LogLevel::value limit = log::LogLevel::value::WARN;
//     log::Formatter::ptr fmt(new log::Formatter("[%d{%H:%M:%S}][%t][%c][%f:%l][%p]%T%m%n"));
//     log::LogSink::ptr stdout_lsp = log::SinkFactory::create<log::StdoutSink>();                                 // 标准输出落地
//     log::LogSink::ptr file_lsp = log::SinkFactory::create<log::FileSink>("./logfile/test.log");                 // 文件落地方式
//     log::LogSink::ptr roll_lsp = log::SinkFactory::create<log::RollBySizeSink>("./logfile/roll-", 1024 * 1024); // 滚动文件落地方式
//     std::vector<log::LogSink::ptr> sinks = {stdout_lsp, file_lsp, roll_lsp};
//     log::Logger::ptr logger(new log::SyncLogger(logger_name, limit, fmt, sinks));

//     logger->debug(__FILE__, __LINE__, "%s", "测试日志");
//     logger->info(__FILE__, __LINE__, "%s", "测试日志");
//     logger->warn(__FILE__, __LINE__, "%s", "测试日志");
//     logger->error(__FILE__, __LINE__, "%s", "测试日志");
//     logger->fatal(__FILE__, __LINE__, "%s", "测试日志");

//     size_t cursize = 0;
//     size_t count = 0;
//     while (cursize < 1024 * 1024 * 10)
//     {
//         logger->fatal(__FILE__, __LINE__, "测试日志-%d", count++);
//         cursize += 20;
//     }

//     return 0;
// }

// 测试代码
// #include "util.hpp"
// #include "level.hpp"
// #include "message.hpp"
// #include "format.hpp"
// #include "sink.hpp"
// #include "logger.hpp"
// #include "buffer.hpp"
// #include <unistd.h>

// int main()
// {
//     //同步日志器建造者模式的测试
//     //先要构造一个建造者出来
//     std::unique_ptr<log::LoggerBuilder> builder(new log::LocalLoggerBuilder());
//     //建造者构建零部件
//     builder->buildLoggerType(log::LoggerType::LOGGER_SYNC);
//     builder->buildLoggerName("sync_logger");
//     builder->buildLoggerLevel(log::LogLevel::value::WARN);
//     builder->buildLoggerFormatter("[%d{%H:%M:%S}][%t][%c][%f:%l][%p]%T%m%n");
//     builder->buildSink<log::StdoutSink>();                                 // 标准输出落地
//     builder->buildSink<log::FileSink>("./logfile/test.log"); // 文件落地方式
//     builder->buildSink<log::RollBySizeSink>("./logfile/roll-", 1024 * 1024); // 滚动文件落地方式
//     //零部件构建好后，用建造者建造对象
//     log::Logger::ptr logger=builder->build();
//     //测试日志打印
//     logger->debug(__FILE__, __LINE__, "%s", "测试日志");
//     logger->info(__FILE__, __LINE__, "%s", "测试日志");
//     logger->warn(__FILE__, __LINE__, "%s", "测试日志");
//     logger->error(__FILE__, __LINE__, "%s", "测试日志");
//     logger->fatal(__FILE__, __LINE__, "%s", "测试日志");

//     size_t cursize = 0;
//     size_t count = 0;
//     while (cursize < 1024 * 1024 * 10)
//     {
//         logger->fatal(__FILE__, __LINE__, "测试日志-%d", count++);
//         cursize += 20;
//     }

//     return 0;
// }

// // 测试代码
// #include "util.hpp"
// #include "level.hpp"
// #include "message.hpp"
// #include "format.hpp"
// #include "sink.hpp"
// #include "logger.hpp"
// #include <unistd.h>
// #include "buffer.hpp"
// #include <fstream>

// int main()
// {
//     // 异步日志器缓冲区测试
//     // 读取文件数据，一点一点写入缓冲区，最终将缓冲区数据写入文件，判断生成的新文件与源文件是否一致
//     std::ifstream ifs("./logfile/test.log", std::ios::binary); // 打开一个文件
//     if (ifs.is_open() == false)
//     {
//         return -1;
//     } // 文件打开失败返回-1
//     // 让读写位置跳转到末尾
//     ifs.seekg(0, std::ios::end);
//     // 获取当前读写位置相对于起始位置的偏移量
//     size_t fsize = ifs.tellg();
//     // 重新让指针跳转到起始位置
//     ifs.seekg(0, std::ios::beg);
//     std::string body;
//     body.resize(fsize);
//     ifs.read(&body[0], fsize);
//     if (ifs.good() == false)
//     {
//         std::cout << "read error!\n";
//         return -1;
//     }
//     // 打开文件，也要关闭
//     ifs.close();
//     std::cout << fsize << std::endl; // 读取文件的数据大小
//     log::Buffer buffer;              // 定义一个缓冲区
//     for (int i = 0; i < body.size(); i++)
//     {
//         buffer.push(&body[i], 1);
//     }
//     std::cout << buffer.readAbleSize() << std::endl; // buffer里面可读的数据大小

//     std::ofstream ofs("./logfile/tem.log", std::ios::binary);
//     size_t rsize = buffer.readAbleSize();
//     for (int i = 0; i < rsize; i++)
//     { 
//         ofs.write(buffer.begin(), 1);
//         if (ofs.good() == false)
//         {
//             std::cout << "writer error!\n";
//             return -1;
//         }
//         buffer.moveReader(1);
//     }
//     ofs.close(); // 关闭文件

//     return 0;
// }

// 测试代码
// #include "util.hpp"
// #include "level.hpp"
// #include "message.hpp"
// #include "format.hpp"
// #include "sink.hpp"
// #include "logger.hpp"
// #include <unistd.h>
// #include "buffer.hpp"
// #include "looper.hpp"
// #include <fstream>
// int main()
// {
 
//     //异步日志器的测试
//     //异步日志器和异步工作器进行联调
//     // //先要构造一个建造者出来
//     std::unique_ptr<log::LoggerBuilder> builder(new log::LocalLoggerBuilder());
//     //建造者构建零部件
//     builder->buildLoggerType(log::LoggerType::LOGGER_ASYNC);
//     builder->buildLoggerName("async_logger");
//     builder->buildLoggerLevel(log::LogLevel::value::WARN);
//     builder->buildLoggerFormatter("[%d{%H:%M:%S}][%t][%c][%f:%l][%p]%T%m%n");
//     builder->buildSink<log::StdoutSink>();                                 // 标准输出落地
//     builder->buildSink<log::FileSink>("./logfile/async.log"); // 文件落地方式
//     // builder->buildSink<log::RoolBySizeSink>("./logfile/roll-", 1024 * 1024); // 滚动文件落地方式
//     //零部件构建好后，用建造者建筑对象
//     log::Logger::ptr logger=builder->build();
//     //测试日志打印
//     logger->debug(__FILE__, __LINE__, "%s", "测试日志");
//     logger->info(__FILE__, __LINE__, "%s", "测试日志");
//     logger->warn(__FILE__, __LINE__, "%s", "测试日志");
//     logger->error(__FILE__, __LINE__, "%s", "测试日志");
//     logger->fatal(__FILE__, __LINE__, "%s", "测试日志");
//     size_t count = 0;
//     while (count < 100000)
//     {
//         logger->fatal(__FILE__, __LINE__, "测试日志-%d", count++);
//     }
//     return 0;
// }

// 测试代码
// #include "util.hpp"
// #include "level.hpp"
// #include "message.hpp"
// #include "format.hpp"
// #include "sink.hpp"
// #include "logger.hpp"
// #include <unistd.h>
// #include "buffer.hpp"
// #include "looper.hpp"
// #include <fstream>

// #include "log.h"

// void test_log(){
//     //日志器管理器
//     //log::Logger::ptr logger=log::LoggerManager::getInstance().getLogger("async_logger");
//    log::Logger::ptr logger=  log::getLogger("async_logger");
//     //测试日志打印
//     logger->debug("%s", "测试日志");
//     logger->info( "%s", "测试日志");
//     logger->warn("%s", "测试日志");
//     logger->error( "%s", "测试日志");
//     logger->fatal( "%s", "测试日志");
//     size_t count = 0;
//     while (count < 100000)
//     {
//         logger->fatal( "测试日志-%d", count++);
//     }


// }

// 测试代码
// #include "../logs/log.h"
// void test_log(){
//     //测试日志打印
//     DEBUG("%s", "测试日志");//注意，宏替换过后命名空间就没了
//     INFO("%s", "测试日志");
//     WARN("%s", "测试日志");
//     ERROR("%s", "测试日志");
//     FATAL("%s", "测试日志");
//     size_t count = 0;
//     while (count < 100000)
//     {
//         FATAL("测试日志-%d", count++);
//     }
// }
// int main()
// {
//     test_log();
//     return 0;
// }


// int main()
// {  
//     //测试日志器管理模块
//     //先要构造一个建造者出来
//     //全局建造者构造日志器
//     std::unique_ptr<log::LoggerBuilder> builder(new log::GlobalLoggerBuilder());
//     //建造者构建零部件
//     builder->buildLoggerName("async_logger");
//     builder->buildLoggerLevel(log::LogLevel::value::WARN);
//     builder->buildLoggerFormatter("[%d{%H:%M:%S}][%t][%c][%f:%l][%p]%T%m%n");
//     builder->buildLoggerType(log::LoggerType::LOGGER_ASYNC);
//     builder->buildEnableUnSafeAsync();//切换模式
//     builder->buildSink<log::StdoutSink>();                                 // 标准输出落地
//     builder->buildSink<log::FileSink>("./logfile/async.log"); // 文件落地方式
   
//     builder->build();
//     // builder->buildSink<log::RoolBySizeSink>("./logfile/roll-", 1024 * 1024); // 滚动文件落地方式
//     test_log();

//     return 0;
// }

// 测试代码
#include "../logs/log.h"

//进行功能测试
void test_log(const std::string &name){
   INFO( "%s", "测试开始");
    log::Logger::ptr logger=log::LoggerManager::getInstance().getLogger(name);
    //测试日志打印
    logger->debug( "%s", "测试日志");
    logger->info( "%s", "测试日志");
    logger->warn( "%s", "测试日志");
    logger->error( "%s", "测试日志");
    logger->fatal("%s", "测试日志");
    INFO( "%s", "测试结束");
}
int main()
{
    std::unique_ptr<log::LoggerBuilder> builder(new log::GlobalLoggerBuilder());
    //建造者构建零部件
    builder->buildLoggerName("async_logger");
    builder->buildLoggerLevel(log::LogLevel::value::DEBUG);
    builder->buildLoggerFormatter("[%d{%H:%M:%S}][%t][%c][%p]%m%n");
    builder->buildLoggerType(log::LoggerType::LOGGER_SYNC);
    builder->buildSink<log::StdoutSink>();                                 // 标准输出落地
    builder->buildSink<log::FileSink>("./logfile/async.log"); // 文件落地方式
    builder->buildSink<log::RollBySizeSink>("./logfile/roll-", 1024 * 1024); // 滚动文件落地方式
    builder->build();
    
    test_log("async_logger");

    return 0;
}
